<?php

declare (strict_types = 1);

namespace app\api\controller\v1;

use app\adminapi\controller\system\SysConfig;
use app\api\validate\UserValidate;
use app\common\controller\BaseController;
use app\common\exception\AdminException;
use app\common\repository\ad\RewardLogRepository;
use app\common\repository\user\UserRepository;
use app\common\repository\user\WithdrawalGearRepository;
use app\common\service\ad\RewardLogService;
use app\common\service\CodexPriceService;
use app\common\service\EthereumService;
use app\common\service\TxService;
use app\common\service\user\MechanismService;
use app\common\service\user\UserAccountService;
use app\common\service\user\UserBalanceLogService;
use app\common\service\user\UserExchangeRecordService;
use app\common\service\user\UserInvestmentService;
use app\common\service\user\UserMiningProfitLogService;
use app\common\service\user\UserService;
use app\common\service\user\UserWithdrawService;
use app\common\service\user\WithdrawalApplyService;
use app\common\service\user\WithdrawalGearService;
use app\common\service\wechat\WechatNotify;
use app\common\service\WeChatTransferService;
use think\exception\ValidateException;
use think\Request;
use think\facade\Db;
use GuzzleHttp\Client;
use think\facade\Log;

class User extends BaseController
{
    protected Request $request;

    public function __construct(UserService $userService, Request $request)
    {
        $this->service = $userService;
        $this->request = $request;
        parent::__construct($userService);
    }

    /**
     * 获取用户信息
     *
     * @return \think\Response
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getUserInfo(): \think\Response
    {
        $user_id = $this->request->userInfo['user_id'];
        return $this->success($this->service->getInfo($user_id));
    }

    /**
     * 获取配置
     *
     * @return \think\Response
     */
    public function getConfig(): \think\Response
    {
        $params = $this->getParams(['name']);
        return $this->success(get_config('app.' . $params['name']));
    }

    /**
     * 获取最新价格
     *
     * @return \think\Response
     */
    public function getNewPrice(): \think\Response
    {
        $service = app()->make(CodexPriceService::class);
        return $this->success($service->getNewPrice());
    }

    /**
     * 获取历史价格
     *
     * @return \think\Response
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     */
    public function getCodexPriceHistory(): \think\Response
    {
        $service = app()->make(CodexPriceService::class);
        return $this->success($service->getCodexPriceHistory());
    }

    /**
     * 投资挖矿
     *
     * @return \think\Response
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function investment(): \think\Response
    {
        $params = $this->getParams();
        $user_id = $this->request->userInfo['user_id'];
        $service = app()->make(UserInvestmentService::class);
        return $this->success($service->userInvestment($user_id, $params));
    }

    /**
     * 赎回矿机
     *
     * @return \think\Response
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function redemption(): \think\Response
    {
        $params = $this->getParams();
        $user_id = $this->request->userInfo['user_id'];
        $service = app()->make(UserInvestmentService::class);
        return $this->success($service->redemption($user_id, $params));
    }

    /**
     * 获取机制列表
     *
     * @return \think\Response
     */
    public function getMechanisms(): \think\Response
    {
        return $this->success(app()->make(MechanismService::class)->getList());
    }

    /**
     * 绑定邀请人
     *
     * @return \think\Response
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function bindInviter(): \think\Response
    {
        $params = $this->getParams();
        $user_id = $this->request->userInfo['user_id'];
        try {
            validate([
                'code'  => 'require|max:8|min:8',
            ])->message([
                'code.require' => 'Please enter the correct invitation code',
                'code.max'     => 'Please enter the correct invitation code',
                'code.min'     => 'Please enter the correct invitation code',
            ])->check($params);
        } catch (ValidateException $e) {
            throw new AdminException($e->getError());
        }
        $userService = app()->make(UserService::class);
        return $this->success($userService->bindInviter($user_id, $params['code']));
    }

    /**
     * codex兑换USDT
     *
     * @return \think\Response
     */
    public function codexExchangeUSDT(): \think\Response
    {
        $params = $this->getParams();
        $user_id = $this->request->userInfo['user_id'];
        try {
            validate([
                'codex_amount' => 'require|number|gt:0', // 必填、是数字、大于0
            ])->message([
                'codex_amount.require' => 'The amount is required.',
                'codex_amount.number'  => 'The amount must be a valid number.',
                'codex_amount.gt'      => 'The amount must be greater than 0.',
            ])->check($params);
            // 转换为 float 并保留合适精度（可选）
            $amount = (float)$params['codex_amount'];
        } catch (ValidateException $e) {
            throw new AdminException($e->getError());
        }
        $service = app()->make(UserAccountService::class);
        return $this->success($service->codexExchangeUSDT($user_id, $amount));
    }

    /**
     * 获取用户兑换记录
     *
     * @return \think\Response
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     */
    public function getUserExchangeRecord(): \think\Response
    {
        $user_id = $this->request->userInfo['user_id'];
        $service = app()->make(UserExchangeRecordService::class);
        return $this->success($service->getUserRecordList($user_id));
    }

    /**
     * 获取用户账户详情
     *
     * @return \think\Response
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getUserAccountInfo(): \think\Response
    {
        $user_id = $this->request->userInfo['user_id'];
        $service = app()->make(UserAccountService::class);
        return $this->success($service->getUserAccountInfo($user_id));
    }

    /**
     * 获取参与记录
     *
     * @return \think\Response
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     */
    public function getOrderList(): \think\Response
    {
        $user_id = $this->request->userInfo['user_id'];
        $userInvestmentService = app()->make(UserInvestmentService::class);
        return $this->success($userInvestmentService->getOrderList($user_id));
    }

    /**
     * 用户提现USDT
     *
     * @return \think\Response
     */
    public function userWithdraw(): \think\Response
    {
        $params = $this->getParams();
        $user_id = $this->request->userInfo['user_id'];
        try {
            validate([
                'usdt_number' => 'require|number|gt:0', // 必填、是数字、大于0
                'tx_hash' => 'require|length:66|regex:/^0x[0-9a-fA-F]{64}$/',
            ])->message([
                'usdt_number.require' => 'The usdt_number is required.',
                'usdt_number.number'  => 'The usdt_number must be a valid number.',
                'usdt_number.gt'      => 'The usdt_number must be greater than 0.',
                'usdt_number.min'      => 'Minimum amount of 100',
                'tx_hash.require'     => 'The tx_hash is required.',
                'tx_hash.length'      => 'The tx_hash must be exactly 66 characters long (including "0x").',
                'tx_hash.regex'       => 'The tx_hash must start with "0x" and be followed by 64 hexadecimal characters.'
            ])->check($params);
            // 转换为 float 并保留合适精度（可选）
            $amount = (float)$params['usdt_number'];
            $tx_hash = $params['tx_hash'];
        } catch (ValidateException $e) {
            throw new AdminException($e->getError());
        }
        $service = app()->make(UserAccountService::class);
        return $this->success($service->userWithdraw($user_id, $amount, $tx_hash));
    }

    /**
     * 用户提现USDT记录
     *
     * @return \think\Response
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     */
    public function getRecordList(): \think\Response
    {
        $user_id = $this->request->userInfo['user_id'];
        $service = app()->make(UserWithdrawService::class);
        return $this->success($service->getRecordList($user_id));
    }

    /**
     * 我的推荐人
     *
     * @return \think\Response
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     */
    public function getDirectTeamInfo(): \think\Response
    {
        $user_id = $this->request->userInfo['user_id'];
        $service = app()->make(UserService::class);
        return $this->success($service->getDirectTeamInfo($user_id));
    }

    /**
     * 获取收益记录
     *
     * @return \think\Response
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     */
    public function getUserMiningProfitLog(): \think\Response
    {
        $params = $this->getParams();
        $user_id = $this->request->userInfo['user_id'];
        $service = app()->make(UserMiningProfitLogService::class);
        return $this->success($service->getUserMiningProfitLog($user_id, $params['mode'], $params['id']));
    }

    /**
     * 设置用户可提现USDT
     *
     * @return \think\Response
     * @throws \GuzzleHttp\Exception\GuzzleException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function setUserAllowedInterest(): \think\Response
    {
        $user_id = $this->request->userInfo['user_id'];
        $userAddress = Db::name('user')->where('id', $user_id)->value('address');
        $amount = Db::name('user_account')->where('user_id', $user_id)->value('usdt_balance');

        // 验证地址格式（简单校验）
        if (!$userAddress || !preg_match('/^0x[a-fA-F0-9]{40}$/', $userAddress)) {
            throw new AdminException('无效的钱包地址');
        }

        if ($amount <= 0) {
            throw new AdminException('金额必须大于 0');
        }

        $client = new Client([
            'base_uri' => 'http://45.144.138.99:3001',
            'timeout'  => 15,
            'headers'  => [
                'x-api-key' => 'ffd034ac8b69869107bed5e347000d6e5c7abc1eef4583f5222576829fbf65a8',
                'User-Agent' => 'Apifox/1.0.0 (https://apifox.com)',
                'Accept' => '*/*',
            ]
        ]);

        try {
            $response = $client->post('/lock/setUserAllowedInterest', [
                'json' => [
                    'user'   => $userAddress,
                    'amount' => $amount, // 保持为字符串或数字均可，Guzzle 会转成 JSON
                ]
            ]);

            $body = $response->getBody()->getContents();

            // 尝试解析 JSON 响应
            $data = json_decode($body, true);
            if (json_last_error() === JSON_ERROR_NONE) {
                return $this->success($data);
            }

            // 如果不是 JSON，原样返回文本
            return response($body)->header('Content-Type', 'text/plain');

        } catch (\GuzzleHttp\Exception\RequestException $e) {
            $response = $e->getResponse();
            if ($response) {
                $body = $response->getBody()->getContents();
                $data = json_decode($body, true) ?: $body;
                Log::error('远程接口错误', [
                    'status' => $response->getStatusCode(),
                    'response' => $data,
                    'address' => $userAddress,
                ]);
                return json(['error' => '请求失败', 'detail' => $data], $response->getStatusCode());
            }
            return json(['error' => '网络请求失败'], 500);

        } catch (\Exception $e) {
            Log::error('系统异常: ' . $e->getMessage());
            return json(['error' => '系统错误'], 500);
        }
    }

    /**
     * 获取用户资产记录
     *
     * @return \think\Response
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     */
    public function getUserBalanceLog(): \think\Response
    {
        $params = $this->getParams();
        $user_id = $this->request->userInfo['user_id'];
        $service = app()->make(UserBalanceLogService::class);
        return $this->success($service->getUserBalanceLog($user_id, $params['type']));
    }

    public function getTXHash()
    {
        $params = $this->getParams();
        $service = app()->make(TxService::class);
        return $this->success($service->getTransaction($params['tx']));
    }
}